#!/bin/python

from subprocess import *
import time
import os
import signal
import threading
class Tester():
    cach={}
    cachlock=threading.Lock()
    def __init__(self):
        pass
    def killme(self):
        os.kill(self.pid,signal.SIGTERM)
        os.kill(self.pid,signal.SIGKILL)
#        self.testProcess.wait()
        
    def test(self,target,testDataFile,standardAnswer,timeOut=5):
        start = time.time()
        f = open(testDataFile)
        self.testProcess = Popen("./"+target,stdin=f,stdout=PIPE)
        self.pid = self.testProcess.pid
        while(self.testProcess.poll()==None and (time.time()-start)<timeOut):
            time.sleep(1)
        if(self.testProcess.poll()==None):#Take too much time to run, maybe there is a infinte loop or deadlock.
            self.killme()              #kill the subprocess
            return -3               #-3, Error:"Run too long"
        result = self.testProcess.communicate();
        if self.testProcess.poll()<0:
            return -2               #-2, Error:"Runtime error"
        result = result[0].split('\n')
        f.close()
        i = 0
        for line in standardAnswer:
            if line!='\n':  #ignore the white row
                if line.replace('\n','').strip()!=result[i].strip():  #check if the result and output are same, 
                                                                      #output MUST be presented in sorted  sequence.
                    return -1      #-1, Error:"Not match result"
                else:
                    i+=1
        if i==len(result)-1:  # The output SHOULD exactly matche the result data length
            return 0
        else :
            return -4 #output longer than the standard result.
            
    def test_(self,target,proid,timeOut=5):
        standardAnswer=[]
        if proid in Tester.cach:
            standardAnswer = Tester.cach[proid]
            print "Cache hit!"
        else:
            print "Cache miss!"
            Tester.cachlock.acquire()
            f = open(proid+".result")
            for line in f:
                standardAnswer.append(line)
            f.close()
            Tester.cach[proid] = standardAnswer
            Tester.cachlock.release()
        return self.test(target+".out","simplebin.in",standardAnswer)
            

if __name__=="__main__":
    t = Tester()
    s = time.time()
    t.test_("test12345","12345")
    e = time.time()
    print e-s
    t.test_("test12345","12345")
    print time.time()-e    
